#! /usr/bin/env python3
# -*- coding: utf-8 -*-

import argparse
import json
import os
import ssl
import urllib.request

ssl._create_default_https_context = ssl._create_unverified_context

config = {
    "src": "./src",
    "meta_file": "meta.json",
    "languages": [
        ("Go", ["golang", "go"]),
        ("PHP", ["php", "Php"])
    ],
}


def init_src(arg):
    os.chdir(os.path.dirname(os.path.realpath(__file__)))
    indexs = arg.split(",")
    res = req_leetcode_all()

    for index in indexs:
        stat = None

        for obj in res['stat_status_pairs']:
            if obj["stat"]["frontend_question_id"] != index:
                continue
            # print(stat)
            stat = obj["stat"]
            stat["cn_title"] = get_cn_title(index)
            break

        if stat:
            init_question(stat)


def req_leetcode_all():
    url = r'https://leetcode-cn.com/api/problems/all/'

    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:47.0) Gecko/20100101 Firefox/47.0',
        'Content-Type': 'application/json'
    }
    req = urllib.request.Request(url=url, headers=headers)
    res = json.loads(urllib.request.urlopen(req).read().decode('utf-8'))

    return res


def get_cn_title(index):
    url = r'https://leetcode-cn.com/graphql'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:47.0) Gecko/20100101 Firefox/47.0',
        'Content-Type': 'application/json'
    }
    raw = {
        "operationName": "getQuestionTranslation",
        "query": "query getQuestionTranslation($lang: String) {\ntranslations: allAppliedQuestionTranslations(lang: $lang) {\n   title\n    questionId\n    __typename\n  }\n}\n",
        "variables": {},
    }

    data = json.dumps(raw)
    data = bytes(data, 'utf-8')
    req = urllib.request.Request(url=url, headers=headers, method="POST", data=data)
    res = json.loads(urllib.request.urlopen(req).read().decode('utf-8'))
    for obj in res['data']['translations']:
        if obj["questionId"] == index:
            return obj["title"]
    return ""


def init_question(stat, label="p"):
    id = int(stat["frontend_question_id"])
    title = stat["question__title"]
    title_cn = stat["cn_title"]
    url = "https://leetcode-cn.com/problems/%s" % stat["question__title_slug"]

    path = "%s/%s%05d" % (config["src"], label, id)

    if not os.path.exists(path):
        os.mkdir(path)

    meta_file = path + "/" + config["meta_file"]

    with open(meta_file, "w+") as fd:
        s = json.dumps({
            "id": id,
            "title": title,
            "title_cn": title_cn,
            "src": url,
        }, indent=2)
        fd.write(s)
    print("[%s]Done - %s(%s)" % (id, title, title_cn))


def read_questions():
    path = config.get("src")
    return (path + "/" + x for x in os.listdir(path))


def fmt_row(info, title=False):
    if title:
        return "| ID | Title | CnTitle | Solution |\n| ---- | ---- | ---- | ---- |"

    id = "%4d" % info.get("id")
    title = "[%s](%s)" % (info.get("title"), info.get('src', ""))
    title_cn = ""
    if info.get("title_cn"):
        title_cn = "[%s](%s)" % (info.get("title_cn"), info.get('src', ""))
    remark = "/".join(info.get("solutions"))

    return "| %s | %s | %s | %s |" % (
        id,
        title,
        title_cn,
        remark,
    )


def gen_md():
    strArr = []
    strArr.append(fmt_row({}, True))

    l = []
    for path in read_questions():
        info = read_meta(path)
        if not info:
            continue
        l.append(info)

    def sortFunc(ele):
        return ele.get("id", 0)

    l.sort(key=sortFunc)
    for x in l:
        strArr.append(fmt_row(x))

    str = "\n".join(strArr)
    # print(str)
    readme_file = "./README.md"
    with open(readme_file, "r+") as fd:
        s = fd.read()
        # print(s)

        fd.seek(0, 0)
        index = s.find("## Solutions")
        s = s[:index]
        s += "## Solutions\n"
        s += str

        # print(s)
        fd.write(s)

    print("Done")


def read_solutions(path):
    base_path = os.path.basename(".")
    dirs = os.listdir(path)
    solutions = []
    for (lang, subs) in config.get("languages"):
        if len(set(subs) & set(dirs)):
            s = "[%s](%s)" % (lang, base_path + "/" + path)
            solutions.append(s)
    return solutions


def read_meta(path):
    metaFile = path + "/" + config.get("meta_file", '')

    if not os.path.isfile(metaFile):
        return None

    with open(metaFile, "r") as fd:
        obj = json.load(fd)

    obj["solutions"] = read_solutions(path)

    return obj


def main():
    parser = argparse.ArgumentParser(description="help to fast deploy")
    parser.add_argument("action", nargs="?", default="", help="should be: 'init' or 'md'")
    parser.add_argument("param", nargs="?", default="", help="'init' question id")
    argf = parser.parse_args()

    if argf.action == "init":
        init_src(argf.param)
    elif argf.action == "md":
        gen_md()
    else:
        parser.print_help()


if __name__ == '__main__':
    main()
